﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace FlyingCircusWebIS.Models
{
    public class AeroportoService: IAeroportoService
    {
        private IAeroportoDAO aeroportoDAO;
        private IVooDAO vooDAO;

        public AeroportoService()
        {
            aeroportoDAO = new AeroportoDAO();
            vooDAO = new VooDAO();
        }

        public void Adicionar(Aeroporto entidade)
        {
            aeroportoDAO.Adicionar(entidade);
        }


        public void Atualizar(Aeroporto entidade)
        {
            aeroportoDAO.Atualizar(entidade);
        }

        public Aeroporto BuscarPorId(int id)
        {
            return aeroportoDAO.BuscarPorId(id);
        }

        public List<ValidationResult> ValidarEntidade(Aeroporto entidade)
        {
            List<ValidationResult> erros = new List<ValidationResult>();

            bool edicao = false;
            if (entidade.IdAeroporto != 0)
                edicao = true;

            if (edicao)
            {
                List<ValidationResult> errosAtualizar = ValidaAtualizar(entidade);
                if (errosAtualizar != null)
                    erros.AddRange(errosAtualizar);
            }
            else
            {
                List<ValidationResult> errosAdicionar = ValidaAdicionar(entidade);
                if (errosAdicionar != null)
                    erros.AddRange(errosAdicionar);
            }

            return erros;
        }

        public List<ValidationResult> ValidaAtualizar(Aeroporto entidade)
        {
            List<ValidationResult> erros = new List<ValidationResult>();

            bool existeNome = aeroportoDAO.Listar().Any(e => e.NomeAeroporto.Equals(entidade.NomeAeroporto, StringComparison.InvariantCultureIgnoreCase)
                                                    && e.IdAeroporto != entidade.IdAeroporto);
            if (existeNome)
                erros.Add(new ValidationResult("Já existe um registro com o nome informado."));


            bool latLongExistente = aeroportoDAO.Listar().Any(e => e.Latitude == entidade.Latitude && e.Longitude == entidade.Longitude
                                                    && e.IdAeroporto != entidade.IdAeroporto);
            if (latLongExistente)
                erros.Add(new ValidationResult("Já existe um registro com a latitude e a longitude informada."));

            return erros;
        }


        public List<ValidationResult> ValidaAdicionar(Aeroporto entidade)
        {
            List<ValidationResult> erros = new List<ValidationResult>();

            bool existeNome = aeroportoDAO.Listar().Any(e => e.NomeAeroporto.Equals(entidade.NomeAeroporto, StringComparison.InvariantCultureIgnoreCase));
            if (existeNome)
                erros.Add(new ValidationResult("Já existe um registro com o nome informado."));


            bool latLongExistente = aeroportoDAO.Listar().Any(e => e.Latitude == entidade.Latitude && e.Longitude == entidade.Longitude);
            if (latLongExistente)
                erros.Add(new ValidationResult("Já existe um registro com a latitude e a longitude informada."));

            return erros;
        }

        public List<Aeroporto> Listar()
        {
            return aeroportoDAO.Listar();
        }

        public List<AeroportoCidade> ListarAeroportoCidade()
        {
            return aeroportoDAO.ListarAeroportoCidade();
        }


        public List<ValidationResult> ValidaRemoverPorId(int id)
        {
            List<ValidationResult> erros = new List<ValidationResult>();

            bool temDependencia = vooDAO.Listar().Any(e => e.IdAeroportoChegada == id || e.IdAeroportoPartida == id);
            if (temDependencia)
                erros.Add(new ValidationResult("TemDependencia", "O registro dependência em outro contexto."));

            return erros;
        }

        public void RemoverPorId(int id)
        {
            aeroportoDAO.RemoverPorId(id);
        }


        public List<AeroportoCidade> ListarAeroportoCidadeFiltro(string nome, string uf)
        {
            List<AeroportoCidade> encontrados = aeroportoDAO.ListarAeroportoCidade().FindAll(a =>
                a.NomeAeroporto.StartsWith(nome, StringComparison.InvariantCultureIgnoreCase) &&
                a.UF.StartsWith(uf, StringComparison.InvariantCultureIgnoreCase));

            return encontrados;
        }

        public List<Aeroporto> ListarAeroportosPorIdCidade(int id)
        {
            return aeroportoDAO.ListarAeroportosPorIdCidade(id);
        }


        public List<SelectListItem> ListarItensAeroportosParaNovo()
        {
            List<SelectListItem> itens = new List<SelectListItem>();
            itens.Add(new SelectListItem { Text = "<Nenhum>", Value = "" });
            return itens;
        }

        private List<SelectListItem> converterRegistrosAeroportosParaList(List<Aeroporto> aeroportos)
        {
            List<SelectListItem> itens = new List<SelectListItem>();
            itens.Add(new SelectListItem { Text = "<Nenhum>", Value = "" });
            foreach (var aeroporto in aeroportos)
            {
                itens.Add(new SelectListItem { Text = aeroporto.NomeAeroporto, Value = aeroporto.IdAeroporto.ToString() });
            }
            return itens;
        }

        public List<SelectListItem> ListarItensAeroportosPorIdCidade(int id)
        {
            List<Aeroporto> aeroportos = ListarAeroportosPorIdCidade(id);
            List<SelectListItem> itens = converterRegistrosAeroportosParaList(aeroportos);
            return itens;
        }
    }
}